﻿#include"stdafx.h"
#include"ServerDB.h"

int ServerDB::Table_Insert(const char*tname, vector<insert_model> vec_insert, string db, string &msg) {
	cur_db = db.c_str();
	CString  tbPath; tbPath = L"data\\" + cur_db + L"\\" + cur_db + L".tb";
	if (!IsTable(tbPath, tname)) {
		msg = "Incorrect table name !";
		return 0;
	}

	CString DBPath; CString Ctname; Ctname = tname;
	DBPath = L"data\\" + cur_db + L"\\" + Ctname + L".tdf";
	file.Open(DBPath, CFile::modeRead | CFile::typeBinary, NULL);
	Table_Tdf tdf; vector<Table_Tdf>vec_tdf;
	while (file.Read(&tdf, sizeof(tdf))) {
		vec_tdf.push_back(tdf);
	}
	file.Close();
	int lenth = vec_tdf.back().order + vec_tdf.back().param;
	//判断字段是否合法 并获得对应的偏移量
	bool index = false;
	//判断字段名是否一致 //完整性维护
	for (unsigned int i = 0; i < vec_insert.size(); i++) {
		for (unsigned j = 0; j < vec_tdf.size(); j++) {
			if (strcmp(vec_insert[i].key.c_str(), vec_tdf[j].name) == 0) {

				if (strcmp(vec_tdf[j].type, "5") == 0 && !IsDateValid(vec_insert[i].value.c_str())) {
					msg = "Invalid date Type!";
					return 0;
				}
				for (int k = 0; k < 5; k++) {
					string intergrity = vec_tdf[j].intergrities[k];
					if (intergrity == "o")
						break;
					//unique完整维护
					if (intergrity == "7" || intergrity == "6") {
						if (!IsUnique(L"data\\" + cur_db + L"\\" + Ctname + L".trd"
							, vec_tdf[j].type, vec_tdf[j].order, lenth, vec_tdf[j].param, vec_insert[i].value)) {
							msg = vec_insert[i].key;
							msg += "  is not unique！";
							return false;
						}
					}
				}
				vec_insert[i].pos = vec_tdf[j].order;
				vec_insert[i].mmSize = vec_tdf[j].param;
				vec_insert[i].index = vec_tdf[j].index;
				vec_insert[i].type = vec_tdf[j].type;
				index = true;
			}
		}
		if (!index) {
			string key; key = vec_insert[i].key;
			msg = "Unknown column " + key + " !";
			return 0;
		}
		index = false;
	}

	vector<insert_model>auto_increase;
	//not null auto_increase primary key
	for (unsigned int i = 0; i < vec_tdf.size(); i++) {
		if (vec_tdf[i].index) {
			bool indexFlag = false;
			for (unsigned int index = 0; index < vec_insert.size(); index++) {
				if (strcmp(vec_tdf[i].name, vec_insert[index].key.c_str()) == 0) {
					indexFlag = true;
					break;
				}
			}
			if (!indexFlag) {
				msg = vec_tdf[i].name;
				msg += "字段是索引字段，不能为空！";
				return false;
			}
		}
		for (int k = 0; k < 5; k++) {
			string intergrity = vec_tdf[i].intergrities[k];
			if (intergrity == "o")
				break;
			if (intergrity == "6" || intergrity == "8") {
				bool flag = false;
				for (unsigned int j = 0; j < vec_insert.size(); j++) {
					if (strcmp(vec_tdf[i].name, vec_insert[j].key.c_str()) == 0) {
						flag = true;
						break;
					}
				}
				if (!flag) {
					msg = vec_tdf[i].name;
					msg = "field " + msg + " is not null !";
					return false;
				}
			}
			if (intergrity == "9") {
				bool flag = false;
				for (unsigned int j = 0; j < vec_insert.size(); j++) {
					if (strcmp(vec_tdf[i].name, vec_insert[j].key.c_str()) == 0) {
						flag = true;
						break;
					}
				}
				if (!flag) {
					insert_model m;
					m.pos = vec_tdf[i].order;
					m.mmSize = vec_tdf[i].param;
					auto_increase.push_back(m);
				}
			}
		}
	}


	DBPath = L"data\\" + cur_db + L"\\" + Ctname + L".trd";
	CFileStatus fileStatus;
	ULONGLONG size;
	if (CFile::GetStatus(DBPath, fileStatus))
	{
		size = fileStatus.m_size;
	}
	//TODO 维护索引
	for (unsigned int index = 0; index < vec_insert.size(); index++) {
		if (vec_insert[index].index) {
			string path = "data\\" + db + "\\" + tname + "_" + vec_insert[index].key + ".tid";
			string judge = db + "_" + tname + "_" + vec_insert[index].key;
			if (vec_insert[index].type == "1") {
				indexInt index_int;
				index_int.key = stoi(vec_insert[index].value);
				index_int.pos = size;
				indexM.insert(path, judge, index_int);
			}
			else if (vec_insert[index].type == "3") {
				indexDouble index_d;
				index_d.key = stod(vec_insert[index].value);
				index_d.pos = size;
				indexM.insert(path, judge, index_d);
			}
			else {
				indexChar index_c;
				Conversion(index_c.key, vec_insert[index].value.c_str());
				index_c.pos = size;
				indexM.insert(path, judge, index_c);
			}

		}
	}

	//写入文件
	file.Open(DBPath, CFile::modeReadWrite | CFile::typeBinary, NULL);
	for (unsigned int i = 0; i < vec_insert.size(); i++) {
		file.Seek(vec_insert[i].pos + size, file.begin);
		if (vec_insert[i].type == "1") {
			int tempInt = 0;
			if (isNum(vec_insert[i].value))
				tempInt = stoi(vec_insert[i].value);
			file.Write(&tempInt, 4);
		}
		else if (vec_insert[i].type == "2") {
			bool tempdouble = false;
			if (vec_insert[i].value == "true")
				tempdouble = true;
			file.Write(&tempdouble, sizeof(bool));
		}
		else if (vec_insert[i].type == "3") {
			double tempdouble = 0;
			try {
				 tempdouble = stod(vec_insert[i].value);
			}
			catch (exception e) {
				tempdouble = 0;
			}
			file.Write(&tempdouble, 8);
		}
		else if (vec_insert[i].type == "5") {
			unsigned long temp = 0;
			int nYear=0, nMonth=0, nDate=0, nHour = 0, nMin = 0, nSec = 0;
			sscanf(vec_insert[i].value.c_str(), "%d-%d-%d %d:%d:%d", &nYear, &nMonth, &nDate, &nHour, &nMin, &nSec);
			CTime t(nYear, nMonth, nDate, nHour, nMin, nSec);
			unsigned long timeValue = (unsigned long)t.GetTime();
			//1495382400
			file.Write(&timeValue, sizeof(timeValue));
		}
		else
			file.Write(vec_insert[i].value.c_str(), vec_insert[i].mmSize);
	}

	//写入自动递增
	int tempSize = size;
	if (size == 0)
		tempSize = lenth;
	for (unsigned int i = 0; i < auto_increase.size(); i++) {
		int tempInt = 0;
		file.Seek(tempSize - lenth + auto_increase[i].pos, file.begin);
		file.Read(&tempInt, 4);
		tempInt = tempInt + 1;
		file.Seek(size + auto_increase[i].pos, file.begin);
		file.Write(&tempInt, 4);
	}

	file.Close();
	msg = "successful !";
	return 1;
}